<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage, ElLoading } from 'element-plus'
import { UploadFilled, Position, Document } from '@element-plus/icons-vue'
interface Message {
  role: 'user' | 'ai'
  content: string
  timestamp: number
  isTyping?: boolean
  file?: {
    name: string
    path: string
  }
}

const messages = ref<Message[]>([])
const inputMessage = ref('')
const isLoading = ref(false)
const isProcessingFile = ref(false)
const isInitialState = ref(true)
const uploadRef = ref()

const handleSendMessage = async () => {
  if (!inputMessage.value.trim()) return

  // 添加用户消息
  messages.value.push({
    role: 'user',
    content: inputMessage.value,
    timestamp: Date.now()
  })

  const userMessage = inputMessage.value
  inputMessage.value = ''
  isLoading.value = true
  isInitialState.value = false

  // 添加AI消息占位符
  const aiMessageIndex = messages.value.length
  messages.value.push({
    role: 'ai',
    content: '',
    timestamp: Date.now(),
    isTyping: true
  })

  try {
    // 使用fetch进行流式接收（FastAPI后端）
    const response = await fetch('http://127.0.0.1:5001/query', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ message: userMessage })
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const reader = response.body?.getReader()
    const decoder = new TextDecoder()

    if (reader) {
      let buffer = ''

      while (true) {
        const { done, value } = await reader.read()

        if (done) break

        buffer += decoder.decode(value, { stream: true })
        const lines = buffer.split('\n')
        buffer = lines.pop() || '' // 保留不完整的行

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            try {
              const data = JSON.parse(line.slice(6))

              if (data.type === 'start') {
                messages.value[aiMessageIndex].content = data.message
                messages.value[aiMessageIndex].isTyping = true
              } else if (data.type === 'content') {
                // 逐字添加内容
                messages.value[aiMessageIndex].content += data.message
                messages.value[aiMessageIndex].isTyping = false
              } else if (data.type === 'status') {
                // 显示状态信息
                messages.value[aiMessageIndex].content = data.message
                messages.value[aiMessageIndex].isTyping = true
              } else if (data.type === 'error') {
                messages.value[aiMessageIndex].content = `错误: ${data.message}`
                messages.value[aiMessageIndex].isTyping = false
                break
              } else if (data.type === 'end') {
                messages.value[aiMessageIndex].isTyping = false
                break
              }
            } catch (e) {
              console.error('解析SSE数据失败:', e)
            }
          }
        }
      }
    }
  } catch (error) {
    console.error('查询错误:', error)
    ElMessage.error('发送消息失败，请重试')
    messages.value[aiMessageIndex].content = '抱歉，发送消息失败，请重试。'
    messages.value[aiMessageIndex].isTyping = false
  } finally {
    isLoading.value = false
  }
}

const handleKeyPress = (e: KeyboardEvent) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault()
    handleSendMessage()
  }
}

const handleUploadSuccess = async (response: any, file: File) => {
  ElMessage.success('文件上传成功')
  const filePath = response.detail.file_path

  // 添加文件消息
  messages.value.push({
    role: 'user',
    content: `已上传文件: ${file.name}`,
    timestamp: Date.now(),
    file: {
      name: file.name,
      path: filePath
    }
  })

  // 处理文件
  await processFile(filePath)
}

const processFile = async (filePath: string) => {
  isProcessingFile.value = true

  // 显示处理中的消息
  messages.value.push({
    role: 'ai',
    content: '正在处理文件，这可能需要一点时间...',
    timestamp: Date.now()
  })

  try {
    const loadingInstance = ElLoading.service({
      fullscreen: true,
      text: '文件处理中...',
      background: 'rgba(0, 0, 0, 0.7)'
    })

    const response = await axios.post(`chat/processFile`, {
      file_path: filePath
    })

    loadingInstance.close()

    // 更新最后一条AI消息为处理完成
    const lastMessage = messages.value[messages.value.length - 1]
    if (lastMessage.role === 'ai') {
      lastMessage.content = `文件处理完成！共处理了 ${response.data.total_processed} 段文本。现在您可以开始提问了。`
    }

    ElMessage.success('文件处理完成')
  } catch (error) {
    console.error('文件处理错误:', error)
    ElMessage.error('文件处理失败，请重试')

    // 更新最后一条AI消息为处理失败
    const lastMessage = messages.value[messages.value.length - 1]
    if (lastMessage.role === 'ai') {
      lastMessage.content = '文件处理失败，请重试。'
    }
  } finally {
    isProcessingFile.value = false
  }
}

const handleUploadError = (err: any) => {
  console.error('上传错误:', err)
  ElMessage.error('文件上传失败，请重试')
}

const chatContainer = ref<HTMLElement | null>(null)

// 自动滚动到底部
const scrollToBottom = () => {
  if (chatContainer.value) {
    chatContainer.value.scrollTop = chatContainer.value.scrollHeight
  }
}

// 监听消息变化，自动滚动
watch(messages, () => {
  nextTick(() => {
    scrollToBottom()
  })
})
</script>

<template>
  <div class="ai-chat-container">
    <div class="chat-messages" ref="chatContainer">
      <div v-if="isInitialState" class="welcome-message">
        <h2>欢迎使用法律文档 AI 助手</h2>
        <p>您可以上传法律文件，或直接提问法律问题</p>
      </div>

      <div v-for="(message, index) in messages"
           :key="index"
           :class="['message', message.role]"
           :style="{ animationDelay: `${index * 0.1}s` }">
        <div class="message-content">
          <div class="message-text">
            {{ message.content }}
            <span v-if="message.isTyping" class="typing-cursor">|</span>
          </div>
          <div v-if="message.file" class="file-attachment">
            <el-icon><Document /></el-icon>
            <span>{{ message.file.name }}</span>
          </div>
        </div>
        <div class="message-time">
          {{ new Date(message.timestamp).toLocaleTimeString() }}
        </div>
      </div>

      <div v-if="isLoading" class="loading-indicator">
        <div class="dot"></div>
        <div class="dot"></div>
        <div class="dot"></div>
      </div>
    </div>

    <div class="input-container">
      <el-input
        v-model="inputMessage"
        type="textarea"
        :rows="2"
        placeholder="请输入您的问题..."
        @keydown="handleKeyPress"
        :disabled="isProcessingFile"
      />
      <div class="button-group">
        <el-upload
          ref="uploadRef"
          class="upload-btn"
          :action="`chat/upload`"
          :show-file-list="false"

          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :multiple="false"
          :disabled="isProcessingFile"
        >
          <el-tooltip content="上传文件" placement="top">
            <el-button :icon="UploadFilled" circle :disabled="isProcessingFile" />
          </el-tooltip>
        </el-upload>

        <el-tooltip content="发送消息" placement="top">
          <el-button
            type="primary"
            @click="handleSendMessage"
            :loading="isLoading"
            :disabled="isProcessingFile || !inputMessage.trim()"
            circle
          >
            <el-icon><Position /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.ai-chat-container {
  width: 95%;
  height: 98%;
  display: flex;
  flex-direction: column;
  border-radius: 8px;
  margin-left: 2.5%;
  margin-top: 1%;

  .chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 15px;
    margin-bottom: 15px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
    backdrop-filter: blur(5px);
    border: 1px solid rgba(255, 255, 255, 0.2);
    min-height: 0;

    .welcome-message {
      text-align: center;
      color: rgba(255, 255, 255, 0.8);
      padding: 40px 0;

      h2 {
        margin-bottom: 10px;
        color: rgba(255, 255, 255, 0.9);
        font-size: 20px;
      }

      p {
        font-size: 16px;
      }
    }

    .message {
      margin-bottom: 15px;
      animation: fadeIn 0.3s ease-out;
      animation-fill-mode: both;
      width: 100%;
      display: flex;
      flex-direction: column;

      &.user {
        align-items: flex-end;

        .message-content {
          background: rgba(64, 158, 255, 0.8);
          color: white;
          border-radius: 12px 12px 0 12px;
          max-width: 80%;
        }
      }

      &.ai {
        align-items: flex-start;

        .message-content {
          background: rgba(255, 255, 255, 0.2);
          color: rgba(255, 255, 255, 0.9);
          border-radius: 12px 12px 12px 0;
          max-width: 80%;
        }
      }

      .message-content {
        padding: 10px 15px;
        word-break: break-word;
        font-size: 16px;

        .message-text {
          white-space: pre-line;

          .typing-cursor {
            animation: blink 1s infinite;
            font-weight: bold;
            color: rgba(64, 158, 255, 0.8);
          }
        }
      }

      .message-time {
        font-size: 12px;
        color: rgba(255, 255, 255, 0.6);
        margin-top: 5px;
      }

      .file-attachment {
        margin-top: 8px;
        padding-top: 8px;
        border-top: 1px dashed rgba(255, 255, 255, 0.2);
        display: flex;
        align-items: center;
        gap: 6px;

        .el-icon {
          font-size: 16px;
        }
      }
    }

    .loading-indicator {
      display: flex;
      justify-content: center;
      padding: 10px;

      .dot {
        width: 8px;
        height: 8px;
        margin: 0 4px;
        background: rgba(64, 158, 255, 0.8);
        border-radius: 50%;
        animation: bounce 1.4s infinite ease-in-out;

        &:nth-child(1) { animation-delay: -0.32s; }
        &:nth-child(2) { animation-delay: -0.16s; }
      }
    }
  }

  .input-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: rgba(255, 255, 255, 0.1);
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
    backdrop-filter: blur(5px);
    border: 1px solid rgba(255, 255, 255, 0.2);

    .button-group {
      display: flex;
      justify-content: flex-end;
      gap: 10px;

      .el-button {
        width: 40px;
        height: 40px;
        padding: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        background: rgba(255, 255, 255, 0.1);
        border: 1px solid rgba(255, 255, 255, 0.2);

        &:hover:not([disabled]) {
          background: rgba(255, 255, 255, 0.2);
        }

        &.el-button--primary {
          background: rgba(64, 158, 255, 0.8);
          border: none;

          &:hover:not([disabled]) {
            background: rgba(64, 158, 255, 0.9);
          }
        }

        &[disabled] {
          opacity: 0.5;
          cursor: not-allowed;
        }

        .el-icon {
          font-size: 18px;
          color: rgba(255, 255, 255, 0.9);
        }
      }
    }

    :deep(.el-textarea__inner) {
      background: rgba(255, 255, 255, 0.1);
      border: 1px solid rgba(255, 255, 255, 0.2);
      color: rgba(255, 255, 255, 0.9);
      font-size: 16px;
      min-height: 60px !important;
      max-height: 120px;

      &::placeholder {
        color: rgba(255, 255, 255, 0.5);
      }

      &:focus {
        border-color: rgba(64, 158, 255, 0.8);
      }

      &[disabled] {
        opacity: 0.5;
        cursor: not-allowed;
      }
    }
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}

@keyframes blink {
  0%, 50% {
    opacity: 1;
  }
  51%, 100% {
    opacity: 0;
  }
}
</style>
